home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / mmlc / source / m2pre.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-17  |  12.0 KB  |  602 lines

  1. /* ------------------------------------------------------------------
  2.                         MML compiler [M2]
  3.                programmed by S.Yamamoto (SHINNOSUKE)
  4.                   m2pre.c  -- pre process source
  5. ------------------------------------------------------------------ */
  6.  
  7. #include    <stdio.h>
  8. #include    <stdlib.h>
  9. #include    <ctype.h>
  10. #include    <string.h>
  11. #include    "m2.h"
  12.  
  13. #define    SUCCSESS    0
  14. #define    FAILURE    (-1)
  15. #define    TRUE    1
  16. #define    FALSE    0
  17. #define    ERR    (-1)
  18. #define    YES    1
  19. #define    NO    0
  20.  
  21. #define    FILENEST    8    /* #include の入れ子レベル */
  22. #define    IFNEST    8    /* #if(n)def の入れ子レベル */
  23. #define    MACRO_MAX    1024    /* 同時に定義できるマクロ数 */
  24. #define    MACNAME_MAX    31    /* マクロ名の有効文字数 */
  25. #define    MACDAT_MAX    255    /* マクロデータの最大長 */
  26. #define    LOOP_MAX    16    /* for next のレベル */
  27. #define    CONDITION_MAX    8    /* 条件コンパイルのレベル */
  28. #define    RDLEN_MAX    509    /* ソース行の最高文字数(バイト) */
  29. #define    WTLEN_MAX    4096    /* 処理後の文字数(バイト) */
  30.  
  31. typedef    struct {
  32.     FILE    *fpi;
  33.     char    name[FILENAME_MAX];
  34.     unsigned    int    line;
  35. } FILEST;
  36.  
  37. FILEST    fileStack[FILENEST];
  38.  
  39. typedef struct {
  40.     int    line;
  41.     long    int    offset;
  42.     int    count;
  43. } LOOP;
  44.  
  45. LOOP    loopStack[LOOP_MAX];
  46.  
  47. typedef struct {
  48.     char    flag;
  49.     char    *name;    /* マクロ名 */
  50.     char    *data;    /* データ */
  51. } MACRO;
  52.  
  53. MACRO    macroStack[MACRO_MAX];
  54.  
  55. int comment;    /* コメントネスト */
  56. int fileNest;   /* ファイル */
  57. int condNest;   /* 条件 */
  58. int loopNest;   /* ループ */
  59. int condition[CONDITION_MAX];   /* 条件 */
  60. int macCount;   /* マクロ数 */
  61.  
  62. char    readBuf[RDLEN_MAX];    /* 読み込みバッファ */
  63. char    writeBuf[WTLEN_MAX];    /* 書き込みバッファ */
  64.  
  65. char    macPara[64] = { 0 };    /* マクロ用パラメータ */
  66.  
  67. /* エラー定義 */
  68. char    *MSG_cntopn    =    "Can't open file '%s'\n";
  69. char    *MSG_cntcrt    =    "Can't creat file '%s'\n";
  70. char    *MSG_cntwrt    =    "Can't open file '%s'\n";
  71. char    *MSG_cntalc    =    "Can't allocate memory (%s)\n";
  72. char    *MSG_misopd    =    "Missing operand (%s)\n";
  73. char    *MSG_miscmt    =    "Missing comment\n";
  74. char    *MSG_undmac    =    "Undefined '%s' macro\n";
  75. char    *MSG_undmml    =    "Undefined this MML '%s'\n";
  76. char    *MSG_undctl    =    "Undefined this control\n";
  77. char    *MSG_undstm    =    "Undefined this statement\n";
  78. char    *MSG_illfnc    =    "Illgel function call %s\n";
  79. char    *MSG_toonst    =    "%s too nested\n";
  80. char    *MSG_toodfn    =    "Too defined\n";
  81. char    *MSG_syntax    =    "Syntax error (%s)\n";
  82. char    *MSG_outwka    =    "Out of work-area\n";
  83. char    *MSG_lbover    =    "Line buffer overflow\n";
  84. char    *MSG_fndsmc    =    "Already defined '%s' macro\n";
  85. char    *MSG_unperr    =    "Unprintable error\n";
  86. char    *MSG_looper    =    "#next without #for\n";
  87. char    *MSG_cdcomp    =    "#else/#endif without #if(n)def\n";
  88. char    *MSG_freerr    =    "%s\n";
  89. char    *MSG_errdtv    =    "Error directive: %s\n";
  90.  
  91. int    errMsg( char *s1,char *s2 ) /* エラー処理 */
  92. {
  93.     char    buf[255];
  94.  
  95.     if( s1 != NULL ) {
  96.         if( s2 != NULL )
  97.             sprintf( buf ,s1 ,s2 );
  98.         else    strcpy( buf ,s1 );
  99.         printf( "%s:%d:%s\n" ,fileStack[fileNest].name
  100.             ,fileStack[fileNest].line ,buf );
  101.     }
  102.     exit( EXIT_FAILURE );
  103. }
  104.  
  105. char    *lineGet( void )    /* 一行読み込む */
  106. {
  107.     for(;;) {
  108.         fileStack[fileNest].line++;
  109.         if( fgets( readBuf ,RDLEN_MAX ,fileStack[fileNest].fpi ) == NULL ) {
  110.             fclose( fileStack[fileNest].fpi );
  111.             if( --fileNest < 0 )    return( NULL );
  112.         }
  113.         else    break;
  114.     }
  115.     return( readBuf );
  116. }
  117.  
  118. int    delComment( void )    /* コメントを取り拡張表記をスペースに */
  119. {
  120.     char    *rp;
  121.     char    *wp;
  122.     char    dat;
  123.  
  124.     rp = &readBuf[0];
  125.     wp = rp;
  126.     while( *rp != '\0' ) {
  127.         if( *rp == '/' && *(rp+1) == '*' ) {
  128.             comment++;
  129.             rp += 2;
  130.             continue;
  131.         }
  132.         if( *rp == '*' && *(rp+1) == '/' ) {
  133.             comment--;
  134.             rp += 2;
  135.             if( comment < 0 )
  136.                 errMsg( MSG_miscmt ,NULL );
  137.             continue;
  138.         }
  139.         if( comment == 0 ) {
  140.             if( *rp == '/' && *(rp+1) == '/' )
  141.                 break;
  142.             dat = *rp;
  143.             rp++;
  144.             if( dat == '\n' )    continue;
  145.             *wp = ( dat >= '\a' && dat <= '\r' )?' ':dat;
  146.             wp++;
  147.         }
  148.         else    rp++;
  149.     }
  150.     *wp = '\0';
  151.     return( SUCCSESS );
  152. }
  153.  
  154. /* マクロ処理サブ */
  155.  
  156. int    macCheck( char *s )    /* マクロの存在を確かめる */
  157. {
  158.     int    i;
  159.     int    ret = ERR;
  160.  
  161.     if( macCount == 0)
  162.         return( ERR );
  163.     for( i=0;i<macCount;i++ ) {
  164.         if( strcmp( s ,macroStack[i].name ) == 0) {
  165.             ret = i;
  166.             break;
  167.         }
  168.     }
  169.     return( ret );    /* [RET] macNumber=found ERR=not found */
  170. }
  171.  
  172. int    macSort( void )    /* 長いマクロ名順にソート(基本選択法)*/
  173. {
  174.     int    i;
  175.     int    j;
  176.     int    s;
  177.     int    max;
  178.     int    chk;
  179.  
  180.     MACRO    dummy;
  181.  
  182.     if( macCount <= 1 )
  183.         return(SUCCSESS);
  184.  
  185.     for( i=0;i<macCount-1;i++ ) {
  186.         max = strlen( macroStack[i].name );
  187.         s = i;
  188.         for( j=i+1;j<macCount;j++ ) {
  189.             chk = strlen( macroStack[j].name );
  190.             if( chk > max ){
  191.                 max = chk;
  192.                 s = j;
  193.             }
  194.         }
  195.         dummy = macroStack[i];
  196.         macroStack[i] = macroStack[s];
  197.         macroStack[s] = dummy;
  198.     }
  199.     return( SUCCSESS );
  200. }
  201.  
  202. int    macExpand( char *wp )    /* マクロ展開 */
  203. {
  204.     char    *s1;
  205.     char    *s2;
  206.     char    *s3;
  207.     char    *msg = "Macro para error";
  208.  
  209.     int    i;
  210.     int    ln;
  211.     int    ld;
  212.     int    n = ERR;
  213.  
  214.     if( strncmp( wp+1 ,"_PARA_" ,6 ) == 0 ) {
  215.         ln = 6;
  216.         ld = strlen( macPara );
  217.         s1 = wp + 1 + ln;
  218.         s2 = wp + ld;
  219.         memmove( s2 ,s1 ,strlen( wp )-ln );
  220.         memcpy( wp ,macPara ,ld );
  221.         return( 0 );
  222.     }
  223.  
  224.     for( i=0;i<macCount;i++ ) {
  225.         ln = strlen( macroStack[i].name );
  226.         if( strncmp( wp+1 ,macroStack[i].name ,ln ) == 0) {
  227.             n = i;
  228.             break;
  229.         }
  230.     }
  231.  
  232.     if( n == ERR )
  233.         return(1);
  234.  
  235.     ld = strlen( macroStack[n].data );
  236.     s1 = wp + 1 + ln;
  237.     s2 = wp + ld;
  238.     
  239.     memmove( s2 ,s1 ,strlen(wp)-ln );
  240.     memcpy( wp ,macroStack[n].data ,ld );
  241.  
  242.     if( macroStack[n].flag == TRUE )
  243.     {
  244.         s3 = s2;
  245.         while( *s3 == ' ' )
  246.             s3++;
  247.  
  248.         if( *s3 != '(' )
  249.             errMsg( MSG_freerr ,msg );
  250.         *s3 = ' ';
  251.         s3++;
  252.         i = 0;
  253.         while( *s3 != ')' ) {
  254.             if( i >= 63 )
  255.                 errMsg( MSG_freerr ,msg );
  256.             macPara[i] = (*s3);
  257.             *s3 = ' ';
  258.             s3++;
  259.             i++;
  260.         }
  261.         *s3 = ' ';
  262.         macPara[i] = '\0';
  263.     }
  264.     return(0);
  265. }
  266.  
  267. void    macRepeat( char *wp )    /* リピート */
  268. {
  269.     char    *msg = "Repeat";
  270.     char    *s1;
  271.     char    *s2;
  272.     char    *buf1;
  273.     char    *buf2;
  274.  
  275.     int    i;
  276.     int    dummy = 0;
  277.     int    num;
  278.     int    l1;
  279.     int    l2 = 1;
  280.  
  281.     s1 = wp + 2;
  282.  
  283.     for(;;) {
  284.         if( *s1 == '\0' )
  285.             errMsg( MSG_syntax ,msg );
  286.         if( *s1 == '(' )    dummy++;
  287.         if( *s1 == ')' )    dummy--;
  288.         if( dummy < 0 ) {
  289.             break;
  290.         }
  291.         s1++;
  292.         l2++;
  293.     }
  294.     *s1 = '\0';
  295.     s1++;
  296.     num = strToInt( &s1 ,0 ,16 ,2 ,msg );
  297.     l1 = strlen(s1) + 1;
  298.  
  299.     if(( buf1 = (char*)malloc( l1 )) == NULL )
  300.         errMsg( MSG_cntalc ,msg );
  301.     if(( buf2 = (char*)malloc( l2 )) == NULL)
  302.         errMsg( MSG_cntalc ,msg );
  303.     strcpy( buf1 ,s1 );
  304.  
  305.     s2 = wp + 2;
  306.     strcpy( buf2 ,s2 );
  307.  
  308.     *wp = '\0';
  309.     for( i=0;i<num;i++ )
  310.         strcat(wp,buf2);
  311.     strcat( wp ,buf1 );
  312.  
  313.     free( buf1 );
  314.     free( buf2 );
  315.     return;
  316. }
  317.  
  318. /* 前処理指令 */
  319.  
  320. int    preInclude( char *p )    /* インクルードファイルのオープン */
  321. {
  322.     char    *msg = "#include";
  323.     char    *s1;
  324.     char    *s2;
  325.  
  326.     s1 = strchr( p ,'<' );
  327.     if( s1 == NULL )
  328.         errMsg( MSG_misopd ,msg );
  329.     s2 = strchr( ++s1 ,'>' );
  330.     if( s2 == NULL || s1 == s2 )
  331.         errMsg( MSG_misopd ,msg );
  332.     *s2 = '\0';
  333.     if( ++fileNest >= FILENEST )
  334.         errMsg( MSG_toonst ,msg );
  335.     strncpy( fileStack[fileNest].name ,s1 ,FILENAME_MAX - 1 );
  336.  
  337.     fileStack[fileNest].line = 0;
  338.     if(( fileStack[fileNest].fpi = fopen(fileStack[fileNest].name , "rt")) == NULL )
  339.         errMsg( MSG_cntopn ,fileStack[fileNest].name );
  340.     return( SUCCSESS );
  341. }
  342.  
  343. int    preDefine( char *p )    /* マクロ定義 */
  344. {
  345.     char    *msg = "#define";
  346.     char    *s;
  347.     char    mn[MACNAME_MAX + 1];
  348.     char    md[MACDAT_MAX + 1];
  349.     char    flag = FALSE;
  350.  
  351.     if( macCount >= MACRO_MAX )
  352.         errMsg( MSG_toodfn ,NULL );
  353.     if( *p == '&' ) {
  354.         flag = TRUE;
  355.         p++;
  356.     }
  357.  
  358.     if( *p == '\0' )
  359.         errMsg( MSG_misopd ,msg );
  360.  
  361.     s = strchr( p ,' ' );
  362.     if( s != NULL ) {
  363.         *s = '\0';
  364.         strncpy( mn ,p ,MACNAME_MAX );
  365.         *s = ' ';
  366.         s = skipSpace( s );
  367.         strncpy( md ,s ,MACDAT_MAX );
  368.     }
  369.     else {
  370.         strncpy( mn ,p ,MACNAME_MAX );
  371.         md[0] = '\0';
  372.     }
  373.     if( macCheck( mn ) != ERR )
  374.         errMsg( MSG_fndsmc ,mn );
  375.     if(( macroStack[macCount].name = malloc( strlen(mn)+1 )) == NULL )
  376.         errMsg( MSG_cntalc ,"macro" );
  377.     if(( macroStack[macCount].data = malloc( strlen(md)+1 )) == NULL )
  378.         errMsg( MSG_cntalc ,"macro" );
  379.  
  380.     strcpy( macroStack[macCount].name ,mn );
  381.     strcpy( macroStack[macCount].data ,md );
  382.  
  383.     macroStack[macCount].flag = flag;
  384.     macCount++;
  385.     macSort();
  386.     return(SUCCSESS);
  387. }
  388.  
  389. int    preUndef( char *p )    /* マクロ解除 */
  390. {
  391.     char    *msg = "#undef";
  392.     char    *s;
  393.     int    n;
  394.  
  395.     if( *p == '\0' )
  396.         errMsg( MSG_misopd ,msg );
  397.     s = strchr( p ,' ' );
  398.     if( s != NULL )
  399.         *s = '\0';
  400.     if(( n = macCheck( p )) == ERR )
  401.         errMsg( MSG_undmac ,p );
  402.  
  403.     free( macroStack[n].name );
  404.     free( macroStack[n].data );
  405.     macCount--;
  406.     if( macCount != 0 ) {
  407.         macroStack[n] = macroStack[macCount];
  408.         macSort();
  409.     }
  410.     return( SUCCSESS );
  411. }       
  412.  
  413. int    preCondition( char *p ,int m )    /* 条件組み込み */
  414. {
  415.     char    *msg = "(conditional compile)";
  416.     char    *s;
  417.     int    n;
  418.  
  419.     if( m == 4 || m == 5 ) {
  420.         if( condNest >= IFNEST )
  421.             errMsg( MSG_toonst ,msg );
  422.         if( *p == '\0' )
  423.             errMsg( MSG_misopd ,msg );
  424.         s = strchr( p ,' ' );
  425.         if( s != NULL )
  426.             *s = '\0';
  427.         n = macCheck( p );
  428.     }
  429.     switch( m ) {
  430.         case 4:
  431.             if( n == ERR )
  432.                 condition[condNest] = 1;
  433.             else    condition[condNest] = 0;
  434.             condNest++;
  435.             break;
  436.         case 5:
  437.             if( n == ERR )
  438.                 condition[condNest] = 0;
  439.             else    condition[condNest] = 1;
  440.             condNest++;
  441.             break;
  442.         case 6:
  443.             if( condNest == 0 )
  444.                 errMsg( MSG_cdcomp ,NULL );
  445.             condition[condNest-1] = ( condition[condNest-1] == 0 )?1:0;
  446.             break;
  447.         case 7:
  448.             if( condNest == 0 )
  449.                 errMsg( MSG_cdcomp ,NULL );
  450.             condNest--;
  451.             break;
  452.     }
  453.     return( SUCCSESS );
  454. }
  455.  
  456. int    preForNext( char *p ,int n )    /* ループ */
  457. {
  458.     int    dummy;
  459.  
  460.     switch( n ) {
  461.         case 8:
  462.             if( loopNest >= LOOP_MAX )
  463.                 errMsg( MSG_toonst ,"#for/#next" );
  464.             loopStack[loopNest].line = fileStack[fileNest].line;
  465.             loopStack[loopNest].offset = ftell( fileStack[fileNest].fpi );
  466.             loopStack[loopNest].count = strToInt( &p,1,256,0,NULL );
  467.             loopNest++;
  468.             break;
  469.         case 9:
  470.             if( loopNest == 0 )
  471.                 errMsg( MSG_looper ,NULL );
  472.             dummy = loopNest - 1;
  473.             loopStack[dummy].count--;
  474.             if( loopStack[dummy].count >= 1 ) {
  475.                 fseek( fileStack[fileNest].fpi,loopStack[dummy].offset,SEEK_SET );
  476.                 fileStack[fileNest].line = loopStack[dummy].line;
  477.             }
  478.             else    loopNest--;
  479.             break;
  480.     }
  481.     return( SUCCSESS );
  482. }
  483.  
  484. int    preDirective( void )    /* 前処理指令メイン */
  485. {
  486.     char    *p;
  487.  
  488.     int    n;
  489.     int    dummy;
  490.  
  491.     static    char    *preCommand[] = {
  492.         "include",
  493.         "define",
  494.         "undef",
  495.         "error",
  496.         "ifdef",
  497.         "ifndef",
  498.         "else",
  499.         "endif",
  500.         "for",
  501.         "next",
  502.         "message",
  503.         "\0"
  504.     };
  505.  
  506.     p = skipSpace( &readBuf[1] );
  507.     n = comSearch( preCommand ,p );
  508.     if( n == ERR )
  509.         errMsg( MSG_undstm ,NULL );
  510.  
  511.     p += strlen( preCommand[n] );
  512.     p = skipSpace( p );
  513.  
  514.     if( n >=4 && n <= 7 ) {
  515.         preCondition( p ,n );
  516.         return( SUCCSESS );
  517.     }
  518.  
  519.     dummy = ( condNest==0 )?0 :condition[condNest-1];
  520.     if( dummy != 0)
  521.         return( SUCCSESS );
  522.  
  523.     switch( n ) {
  524.         case 0:
  525.             preInclude( p );
  526.             break;
  527.         case 1:
  528.             preDefine( p );
  529.             break;
  530.         case 2:
  531.             preUndef( p );
  532.             break;
  533.         case 3:
  534.             errMsg( MSG_errdtv ,p );
  535.             break;
  536.         case 8:
  537.         case 9:
  538.             preForNext( p ,n );
  539.             break;
  540.         case 10:
  541.             printf( "%s\n" ,p );
  542.             break;
  543.     }
  544.     return( SUCCSESS );
  545. }
  546.  
  547. /* 前処理メイン関数 */
  548.  
  549. int    Pre_open( const char *fn )    /* ファイルオープン */
  550. {
  551.     if(( fileStack[0].fpi = fopen( fn ,"rt" )) == NULL ) {
  552.         printf( MSG_cntopn ,fn );
  553.         errMsg( NULL,NULL );
  554.     }
  555.  
  556.     comment = 0;
  557.     fileNest = 0;
  558.     condNest = 0;
  559.     loopNest = 0;
  560.     macCount = 0;
  561.  
  562.     strcpy( fileStack[0].name ,fn );
  563.     fileStack[0].line = 0;
  564.     return( SUCCSESS );
  565. }
  566.  
  567. char    *Pre_fgets( void )    /* 一行読み込み */
  568. {
  569.     char    *rp;
  570.     char    *wp;
  571.     char    *wb;
  572.     int    dummy;
  573.  
  574.     wb = &writeBuf[0];
  575.  
  576.     for(;;) {
  577.         if( lineGet() == NULL )
  578.             return( NULL );
  579.         delComment();    /* コメントを取る */
  580.  
  581.         dummy = ( condNest == 0 ) ? 0 :condition[condNest-1];
  582.         if( readBuf[0] != '#' && dummy == 0 )
  583.             break;
  584.         if( readBuf[0] == '#' )
  585.             preDirective();    /* 前処理指令 */
  586.     }
  587.  
  588.     rp = &readBuf[0];
  589.     wp = wb;
  590.     strcpy( wp ,rp );
  591.     
  592.     while( *wp != '\0' ) {
  593.         if( *wp == '$' ) {
  594.             if( *(wp+1) != '(' )
  595.                 wp += macExpand( wp );
  596.             else    macRepeat( wp );
  597.         }
  598.         else    wp++;
  599.     }
  600.     return( wb );
  601. }
  602.